package com.liming.cart.service.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liming.cart.mapper.CartItemMircoMapper;
import com.liming.cart.service.CartItemMircoService;
import com.liming.common.exception.BusinessException;
import com.liming.common.pojo.entity.cart.CartItem;
import com.liming.common.util.mybatisplus.MPUtil;
import com.liming.stock.client.StockClient;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author liming
 * @date 2025/1/22
 */
@Slf4j
@Service
@AllArgsConstructor
public class CartItemMircoServiceImpl extends ServiceImpl<CartItemMircoMapper, CartItem>
        implements CartItemMircoService, MPUtil<CartItem> {

    private final StockClient stockClient;
    private final CartItemMircoMapper cartItemMircoMapper;
    // private final CartMircoService cartMircoService; 不能注入，循环依赖

    @Override
    public Boolean reduceItemById(Long id) {
        CartItem item = getById(id);
        Assert.notNull(item, () -> new BusinessException("购物车商品不存在"));
        Assert.isTrue(item.getQuantity() > 1, () -> new BusinessException("购物车商品数量为1，不能再减少"));
        boolean update = lambdaUpdate()
                .eq(CartItem::getId, id)
                .setSql("quantity = quantity - 1")
                .update();
        Assert.isTrue(update, () -> new BusinessException("减少购物车商品数量失败"));
        return true;
    }

    @Override
    public Boolean addItemById(Long id) {
        CartItem item = getById(id);
        Assert.notNull(item, () -> new BusinessException("购物车商品不存在"));
        Integer itemQuantity = item.getQuantity();
        // 查询商品库存
        checkProductStock(item.getProductId(), itemQuantity);
        boolean update = lambdaUpdate()
                .eq(CartItem::getId, id)
                .setSql("quantity = quantity + 1")
                .update();
        Assert.isTrue(update, () -> new BusinessException("增加购物车商品数量失败"));
        return true;
    }

    /**
     * 检查商品库存
     *
     * @param productId    商品ID
     * @param itemQuantity 增加商品数量
     */
    private void checkProductStock(Long productId, Integer itemQuantity) {
        Integer stockQuantity = stockClient.getAvailableQuantity(productId);
        Assert.isTrue(stockQuantity > itemQuantity, () -> new BusinessException("商品库存不足"));
    }

    @Override
    public boolean addItemQuantity(CartItem cartItem, Long productId, Integer quantity) {
        // 首次添加购物车使用
        // 查询商品库存
        checkProductStock(productId, cartItem.getQuantity());
        boolean update = cartItemMircoMapper.addItemQuantity(cartItem.getId(), quantity);
        Assert.isTrue(update, () -> new BusinessException("增加购物车商品数量失败"));
        return true;
    }

    @Override
    public Boolean removeItemsByIds(List<Long> ids) {
        Assert.isTrue(removeByIds(ids), () -> new BusinessException("删除购物车商品失败"));
        return true;
    }

    @Override
    public Boolean removeItemsByProductIds(Long cartId, List<Long> productIds) {
        // 根据购物车ID和购物车中商品ID删除购物车商品
        boolean remove = lambdaUpdate()
                .eq(CartItem::getCartId, cartId)
                .in(CartItem::getProductId, productIds)
                .remove();
        Assert.isTrue(remove, () -> new BusinessException("删除购物车商品失败"));
        return true;
    }
}
